package com.secxiot.provider.communication.service.impl;

import com.secxiot.common.constant.ServerStatusEnum;
import com.secxiot.common.exception.BaseRuntimeException;
import com.secxiot.common.utils.IdWorker;
import com.secxiot.provider.communication.dao.*;
import com.secxiot.provider.communication.dto.CommunicationCreateDto;
import com.secxiot.provider.communication.dto.CommunicationDetailCreateDto;
import com.secxiot.provider.communication.entity.*;
import com.secxiot.provider.communication.service.CommunicationService;
import com.secxiot.provider.communication.vo.*;
import com.secxiot.provider.system.dto.FileLogDto;
import com.secxiot.provider.user.dao.DeptDao;
import com.secxiot.provider.user.dao.UserExtraDao;
import com.secxiot.provider.user.dto.DeptDto;
import com.secxiot.provider.user.dto.UserDeptDto;
import com.secxiot.provider.user.entity.UserExtra;
import com.secxiot.provider.user.entity.UserExtraExample;
import com.secxiot.provider.user.service.DeptService;
import com.secxiot.provider.user.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;

@Transactional
@Service
public class CommunicationServiceImpl implements CommunicationService {

    private static Logger LOG = LoggerFactory.getLogger(CommunicationServiceImpl.class);

    @Autowired
    IdWorker idWorker;

    @Autowired
    private CommunicationDao communicationDao;

    @Autowired
    private CommunicationDetailDao communicationDetailDao;

    @Autowired
    private CommunicationDeptDao communicationDeptDao;

    @Autowired
    private UserExtraDao userExtraDao;

    @Autowired
    private DeptDao deptDao;

    @Autowired
    private UserService userService;

    @Autowired
    private DeptService deptService;

    @Autowired
    private CommunicationAttachmentDao communicationAttachmentDao;

    @Autowired
    private CommunicationDetailAttachmentDao communicationDetailAttachmentDao;

    /**
     * 医生/护士查看：病患管理患者列表（可选）.
     *
     * @see com.secxiot.provider.communication.service.CommunicationService#getPatientList(java.lang.Long,
     * java.lang.String, java.lang.String, long, java.lang.Long)
     */
    @Override
    public List<CommunicatePatientVo> getPatientList(Long userId, String userType, String patientName, long pageNo, Long pageSize) {
        // 获取用户直属部门id
        DeptDto dept = deptDao.getDeptByUserId(userId);
        if (dept == null) {
            throw new BaseRuntimeException(ServerStatusEnum.NO_DEPT);
        }
        Long deptId = dept.getDeptId();
        List<CommunicatePatientVo> list = communicationDao.getPatientList(deptId, userId, userType, patientName, pageNo, pageSize);
        if (CollectionUtils.isEmpty(list)) {
            return list;
        }

        list.stream().forEach(item -> {
            // 获取主题对话信息
            List<CommunicatePatientVo> extroList = communicationDao.getReadInfoOfDoctor(userId, item.getPatientId());
            if (!CollectionUtils.isEmpty(extroList)) {
                // 医生查询则返回最新对话时间
                item.setNewCommunicationTime(extroList.get(0).getNewCommunicationTime());
                if (userType.equals("0000100004") || userType.equals("0000100005")) {
                    // 【主题对话】未读数量
                    item.setUnreadFlag(extroList.get(0).getUnreadFlag());
                }
            }
        });
        return list;
    }

    /**
     * 病患管理-我的医生（可选）.
     *
     * @see com.secxiot.provider.communication.service.CommunicationService#getDoctorList(java.lang.Long,
     * java.lang.String, long, java.lang.Long)
     */
    @Override
    public List<CommunicateDoctorVo> getDoctorList(Long patientId, String doctorName, long pageNo, Long pageSize) {
        List<CommunicateDoctorVo> list = communicationDao.getDoctorList(patientId, doctorName, pageNo, pageSize);
        if (CollectionUtils.isEmpty(list)) {
            return list;
        }
        list.stream().forEach(item -> {
            // 获取主题对话信息
            List<CommunicateDoctorVo> extroList = communicationDao.getReadInfoOfPatient(patientId, item.getDoctorId());
            if (!CollectionUtils.isEmpty(extroList)) {
                // 医生查询则返回最新对话时间
                item.setNewCommunicationTime(extroList.get(0).getNewCommunicationTime());
                // 【主题对话】未读数量
                item.setUnreadFlag(extroList.get(0).getUnreadFlag());
            }
        });
        return list;
    }

    /**
     * 添加新主題.
     *
     * @see com.secxiot.provider.communication.service.CommunicationService#createCommunication(com.secxiot.provider.communication.dto.CommunicationCreateDto)
     */
    @Override
    public Long createCommunication(CommunicationCreateDto communicationCreateDto) {

        // 获取创建者用户类型
        Date date = new Date();
        String createrType = userService.getById(communicationCreateDto.getCreatorId()).getType();
        // 获取接收者者用户类型
        String reciverType = userService.getById(communicationCreateDto.getReceiverId()).getType();

        /**
         * 1、保存主题表
         */
        Communication communication = new Communication();
        Long communicationId = idWorker.nextId();
        communication.setId(communicationId);
        // 标题
        communication.setTitle(communicationCreateDto.getTitle());
        communication.setReceiveUser(communicationCreateDto.getReceiverId());
        communication.setReadFlag(0);
        communication.setLatestTime(date);
        // 医生/患者未读消息个数
//		if (createrType.equals("0000100004")||createrType.equals("0000100005")) {
//			communication.setCreatorUnread(0);
//			communication.setReceiverUnread(1);
//		} else if (reciverType.equals("0000100004")||reciverType.equals("0000100005")) {
//			communication.setCreatorUnread(1);
//			communication.setReceiverUnread(0);
//		}
//		if(createrType.equals("0000100001")){ // 患者
//			communication.setCreatorUnread(1);
//			communication.setReceiverUnread(0);
//		}else if(!createrType.equals("0000100001")){// 医护
//			communication.setCreatorUnread(0);
//			communication.setReceiverUnread(1);
//		}
        communication.setCreatorUnread(1);
        communication.setReceiverUnread(0);
        communication.setDelFlag(0);
        communication.setCreateUser(communicationCreateDto.getCreatorId());
        communication.setCreateTime(date);
        communication.setUpdateTime(date);
        int result = communicationDao.insert(communication);
        if (result > 0) {
            LOG.info("保存主题表成功");
        } else {
            LOG.error("保存主题表失败");
        }
        /**
         * 2、保存主题附件信息
         */
        List<FileLogDto> attachments = communicationCreateDto.getAttachments();
        if (!CollectionUtils.isEmpty(attachments)) {
            attachments.stream().forEach(item -> {
                CommunicationAttachment communicationAttachment = new CommunicationAttachment();
                communicationAttachment.setId(idWorker.nextId());
                communicationAttachment.setCommunicationId(communicationId);
                communicationAttachment.setFileLogId(item.getFileLogId());
                communicationAttachment.setFileType(item.getFileType());
                communicationAttachment.setFileUri(item.getFileUri());
                communicationAttachment.setDelFlag(0);
                int attachResult = communicationAttachmentDao.insert(communicationAttachment);
                if (attachResult > 0) {
                    LOG.info("保存主题附件成功");
                } else {
                    LOG.error("保存主题附件失败");
                }
            });
        }
        /**
         * 3、保存主题部门关系表
         *  1、发起人 不是患者类型 查询创建人
         */
        List<UserDeptDto> superDepts = new ArrayList<UserDeptDto>();
        if (!createrType.equals("0000100001")) {
            superDepts = deptService.listSupperDeptByUserId(communicationCreateDto.getCreatorId());
        } else if (!reciverType.equals("0000100001")) {
            superDepts = deptService.listSupperDeptByUserId(communicationCreateDto.getReceiverId());
        }
		/*superDepts.stream().forEach(item -> {
			CommunicationDept communicationDept = new CommunicationDept();
			communicationDept.setId(idWorker.nextId()+ );
			communicationDept.setCommunicatId(communicationId);
			communicationDept.setDeptId(item.getDeptId());
			communicationDept.setDirectFlag(item.getDirectFlag());
			int commDeptResult = communicationDeptDao.insert(communicationDept);
			if (commDeptResult > 0) {
				LOG.info("保存主题部门成功");
			} else {
				LOG.error("保存主题部门失败");
			}
		});
		superDepts.size();*/

        for (int i = 0; i < superDepts.size(); i++) {
            UserDeptDto item = superDepts.get(i);
            CommunicationDept communicationDept = new CommunicationDept();
            communicationDept.setId(idWorker.nextId() + i);
            communicationDept.setCommunicatId(communicationId);
            communicationDept.setDeptId(item.getDeptId());
            communicationDept.setDirectFlag(item.getDirectFlag());
            int commDeptResult = communicationDeptDao.insert(communicationDept);
            if (commDeptResult > 0) {
                LOG.info("保存主题部门成功");
            } else {
                LOG.error("保存主题部门失败");
            }
        }
        return communication.getId();
    }

    @Override
    public Long createCommunicationDetail(CommunicationDetailCreateDto communicationCreateDetailDto) {
        Communication communication = communicationDao
                .selectByPrimaryKey(communicationCreateDetailDto.getCommunicationId());
        if (communication == null) {
            throw new BaseRuntimeException(ServerStatusEnum.COMMUNICATION_NOT_EXIST);
        }
        /**
         * 1、保存主题对话表
         */
        Date date = new Date();
        CommunicationDetail communicationDetail = new CommunicationDetail();
        Long communicationDetailId = idWorker.nextId();
        communicationDetail.setId(communicationDetailId);
        communicationDetail.setCommunicatId(communicationCreateDetailDto.getCommunicationId());
        communicationDetail.setContent(communicationCreateDetailDto.getTitle());
        communicationDetail.setReadFlag(0);
        communicationDetail.setCreateUser(communicationCreateDetailDto.getCreatorId());
        communicationDetail.setCreateTime(date);
        communicationDetail.setDelFlag(0);
        communicationDetail.setUpdateTime(date);
        int detailResult = communicationDetailDao.insert(communicationDetail);
        if (detailResult > 0) {
            LOG.info("保存主题对话成功");
        } else {
            LOG.error("保存主题对话失败");
        }
        /**
         * 2、保存主题对话附件表
         */
        List<FileLogDto> attachments = communicationCreateDetailDto.getAttachments();
        if (!CollectionUtils.isEmpty(attachments)) {
            attachments.stream().forEach(item -> {
                CommunicationDetailAttachment communicationAttachment = new CommunicationDetailAttachment();
                communicationAttachment.setCommunicationDetailId(communicationDetailId);
                communicationAttachment.setId(idWorker.nextId());
                communicationAttachment.setFileLogId(item.getFileLogId());
                communicationAttachment.setFileType(item.getFileType());
                communicationAttachment.setFileUri(item.getFileUri());
                communicationAttachment.setDelFlag(0);
                int attachResult = communicationDetailAttachmentDao.insert(communicationAttachment);
                if (attachResult > 0) {
                    LOG.info("保存主题对话附件成功");
                } else {
                    LOG.error("保存主题对话附件失败");
                }
            });
        }

        /**
         * 3、修改主题表读取信息
         */
        communication.setLatestTime(date);
        communication.setUpdateTime(date);
        // 获取创建者用户类型
        String createrType = userService.getById(communicationCreateDetailDto.getCreatorId()).getType();
        if (!createrType.equals("0000100001")) {// 发起人不是是患者，患者增加一条未读消息
            communication.setReceiverUnread(communication.getReceiverUnread() + 1);
        } else if (createrType.equals("0000100001")) {// 发起人是患者，医生增加一条未读消息
            communication.setCreatorUnread(communication.getCreatorUnread() + 1);
        }
        int flag = communicationDao.updateByPrimaryKey(communication);
        if (flag > 0) {
            LOG.info("修改主题表读取信息成功");
        } else {
            LOG.error("修改主题表读取信息失败");
        }
        return communicationDetail.getId();
    }

    /**
     * 获取主题列表
     *
     * @param userId    登录用户id
     * @param userType  登录用户类型，字典00001
     * @param title     主题标题
     * @param doctorId  医生/护士id
     * @param patientId 患者id
     * @param pageNo    页码
     * @param pageSize  条数
     * @return
     */
    @Override
    public List<CommunicationVo> getCommunicationlist(Long userId, String userType, String title, Long doctorId,
                                                      Long patientId, long pageNo, Long pageSize) {

        Map<String, Object> map = new HashMap<String, Object>();
        map.put("title", title);
        map.put("patientId", patientId);
        map.put("pageNo", pageNo);
        map.put("pageSize", pageSize);
        List<CommunicationVo> list = new ArrayList<CommunicationVo>();
//		if (!userType.equals("0000100004") && !userType.equals("0000100001")) {
//			// 获取用户直属部门id
//			Long deptId = deptDao.getDeptByUserId(doctorId).getDeptId();
//			map.put("deptId", deptId);
//			// 不是医生或者患者，不需要查未读数量
//			list = communicationDao.getCommunicationListOfOther(map);
//		} else {
        map.put("doctorId", doctorId);
        map.put("userType", userType);
        list = communicationDao.getCommunicationListOfDocAndPa(map);
        //}
        if (!CollectionUtils.isEmpty(list)) {
            list.stream().forEach(item -> {
                List<CommunicationAttachVo> att = communicationAttachmentDao.getListByCommunicationId(item.getCommunicationId());
                if (!CollectionUtils.isEmpty(att)) {
                    item.setAttachments(att);
                }
            });
        }
        return list;
    }

    /**
     * 获取主题对话列表.
     */
    @Override
    public List<CommunicationDetailVo> getCommunicationDetaillist(Long readUserId, Long communicationId, long pageNo,
                                                                  Long pageSize) {
        // 获取主题对话列表
        List<CommunicationDetailVo> list = communicationDetailDao.getCommunicationDetaillist(communicationId, pageNo, pageSize);
        if (!CollectionUtils.isEmpty(list)) {
            list.stream().forEach(item -> {
                // 获取对话附件
                List<CommunicationAttachVo> att = communicationDetailAttachmentDao
                        .getListByCommunicationDetailId(item.getCommunicationDetailId());
                if (!CollectionUtils.isEmpty(att)) {
                    item.setAttachments(att);
                }
            });
        }
        this.updateCommunicationReadFlag(communicationId, readUserId);
        return list;
    }

    /**
     * 修改主题状态为已读.
     */
    public boolean updateCommunicationReadFlag(Long communicationId, Long readUserId) {
        Date date = new Date();
        Communication communication = communicationDao.selectByPrimaryKey(communicationId);
        if (null == communication) {
            LOG.error("未查找到该主题信息");
            return false;
        }
        if (0 == communication.getReadFlag() && readUserId.longValue() == communication.getReceiveUser().longValue()) {
            communication.setReadFlag(1);// 读取状态改为已读
            communication.setUpdateTime(date);
            communicationDao.updateByPrimaryKey(communication);
        }
        // 修改主题对话读取状态
        int detailFlag = communicationDetailDao.updateCommunDetailReadFlag(readUserId, communicationId);
        if (detailFlag != 0) {
            LOG.info("修改主题对话读取状态为已读");
        }
        // 修改主题的医生/患者未读数量
        communication = communicationDao.selectByPrimaryKey(communicationId);
        String userType = userService.getById(readUserId).getType();// 读取人用户类型
        if (!"0000100001".equals(userType)) {// 医生 科主任
            communication.setCreatorUnread(0);
        } else if ("0000100001".equals(userType)) {// 患者
            communication.setReceiverUnread(0);
        }
        communication.setUpdateTime(date);
        communicationDao.updateByPrimaryKey(communication);

        return true;
    }

    @Override
    public CommunicationUnreadCount getUnreadCount(Long readUserId, String userType) {
        return communicationDao.getUnreadCount(readUserId, userType);
/*		CommunicationExample example = new CommunicationExample();
		int sum = 0;
		if ("0000100004".equals(userType)) {// 医生
			example.clear();
			example.setFields("id,creator_unread");
			example.createCriteria().andCreateUserEqualTo(readUserId).andCreatorUnreadGreaterThan(0);
			example.or().andReceiveUserEqualTo(readUserId).andCreatorUnreadGreaterThan(0);
			List<Communication> cr = communicationDao.selectByExample(example);
			sum = cr.stream().mapToInt(Communication::getCreatorUnread).sum();
		} else if ("0000100001".equals(userType)) {// 患者
			example.clear();
			example.setFields("id,receiver_unread");
			example.createCriteria().andCreateUserEqualTo(readUserId).andReceiverUnreadGreaterThan(0);
			example.or().andReceiveUserEqualTo(readUserId).andReceiverUnreadGreaterThan(0);
			List<Communication> re = communicationDao.selectByExample(example);
			sum = re.stream().mapToInt(Communication::getReceiverUnread).sum();
		}

		count = new CommunicationUnreadCount();
		count.setCommunicationCount(0);
		count.setDetailCount(sum);
		return count;*/
    }

    @Override
    public boolean deleteCommunication(Long userId, Long communicationId) {
        Communication communication = communicationDao.selectByPrimaryKey(communicationId);
        if (null == communication) {
            LOG.error("未查找到该主题信息");
            return false;
        }
        if (!userId.equals(communication.getCreateUser())) {
            LOG.error("无删除权限");
            return false;
        }
        // 1、删除主题对话表+附件表
        communicationDetailAttachmentDao.deleteByCommunicationId(communicationId);
        communicationDetailDao.deleteByCommunicationId(communicationId);
        // 2、删除主题表+附件表
        communicationAttachmentDao.deleteByCommunicationId(communicationId);
        communicationDao.deleteByCommunicationId(communicationId);
        return true;
    }

    /**
     * 修改医生患者备注床号信息.
     */
    @Override
    public boolean updateUserExtro(Long userId, String memo, String beds) {
        UserExtraExample example = new UserExtraExample();
        Date date = new Date();
        // 备注
        if (!StringUtils.isEmpty(memo)) {
            example.clear();
            example.createCriteria().andUserIdEqualTo(userId).andExtraNameEqualTo("memo").andValidEqualTo(1);
            List<UserExtra> mc = userExtraDao.selectByExample(example);
            if (CollectionUtils.isEmpty(mc)) {
                UserExtra memovo = new UserExtra();
                // 新增
                memovo.setId(idWorker.nextId());
                memovo.setUserId(userId);
                memovo.setExtraName("memo");
                memovo.setExtraValue(memo);
                memovo.setValid(1);
                memovo.setCreateTime(date);
                memovo.setUpdateTime(date);
                userExtraDao.insert(memovo);
            } else {
                // 修改
                UserExtra usermemo = mc.get(0);
                usermemo.setExtraValue(memo);
                usermemo.setUpdateTime(date);
                userExtraDao.updateByPrimaryKeySelective(usermemo);
            }
        }
        // 床号
        if (!StringUtils.isEmpty(beds)) {
            example.clear();
            example.createCriteria().andUserIdEqualTo(userId).andExtraNameEqualTo("beds").andValidEqualTo(1);
            List<UserExtra> mc = userExtraDao.selectByExample(example);
            if (CollectionUtils.isEmpty(mc)) {
                UserExtra bedsvo = new UserExtra();
                // 新增
                bedsvo.setId(idWorker.nextId());
                bedsvo.setUserId(userId);
                bedsvo.setExtraName("beds");
                bedsvo.setExtraValue(beds);
                bedsvo.setValid(1);
                bedsvo.setCreateTime(date);
                bedsvo.setUpdateTime(date);
                userExtraDao.insert(bedsvo);
            } else {
                // 修改
                UserExtra usermemo = mc.get(0);
                usermemo.setExtraValue(beds);
                usermemo.setUpdateTime(date);
                userExtraDao.updateByPrimaryKeySelective(usermemo);
            }
        }
        return true;
    }

    /**
     * 获取主题对话列表
     */
    @Override
    public List<CommunicationTalkVo> getcommunicationTalklist(Long talkUserId, Long userId, long pageNo, Long pageSize) {
        return communicationDao.getcommunicationTalklist(talkUserId, userId, pageNo * pageSize, pageSize);
    }

    @Override
    public Long sendTalkMessage(Long talkUserId, Long user, String content, Integer contentType) {
        Date date = new Date();
        Long communicationId = idWorker.nextId();
        Communication record  = new Communication();
        record.setId(communicationId);
        record.setContent(content);
        record.setContentType(contentType);
        record.setDelFlag(0);
        record.setReadFlag(0);
        record.setReceiveUser(talkUserId);
        record.setCreateUser(user);
        record.setCreateTime(date);
        record.setLatestTime(date);
        record.setUpdateTime(date);
        return communicationDao.insertSelective(record);
    }
}
